package com.reform.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.reform.config.JwtTokenUtil;
import com.reform.mapper.*;
import com.reform.pojo.common.Dealt;
import com.reform.pojo.project.*;
import com.reform.res.Result;
import com.reform.res.ResultCode;
import com.reform.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.reform.utils.JSONToArrUtils;
import com.reform.utils.RedisUtils;
import com.reform.utils.UUIDUtils;
import com.reform.utils.VerifycUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.sql.SQLException;
import java.util.*;

/**
 * <p>
 * VIEW 服务实现类
 * </p>
 *
 * @author mortale
 * @since 2021-07-21
 */
@Service
public class ViewProjectServiceImpl extends ServiceImpl<ViewProjectMapper, ViewProject> implements IViewProjectService {

    @Autowired
    ViewProjectMapper viewProjectMapper;
    @Autowired
    ProjectMapper projectMapper;
    @Autowired
    ProjectMemberMapper projectMemberMapper;
    @Autowired
    ProjectSearchingMapper projectSearchingMapper;
    @Autowired
    ProjectTeachingMapper projectTeachingMapper;
    @Autowired
    IViewProjectMemberService viewProjectMemberService;
    @Autowired
    IProjectService projectService;
    @Autowired
    IProjectMemberService projectMemberService;
    @Autowired
    IProjectSearchingService projectSearchingService;
    @Autowired
    IProjectTeachingService projectTeachingService;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    JwtTokenUtil jwtTokenUtil;

    @Value("${jwt.expireTime}")
    Long expireTime;

    @Override
    public Result getAllProject() throws SQLException {
        List<ProjectInfo> projectInfos;
        projectInfos = (List<ProjectInfo>) redisUtils.get("project");
        if (!VerifycUtils.verifyNullOrEmptyUtils(projectInfos)) {
            projectInfos = new ArrayList<>();
            List<Project> projectList = projectMapper.selectList(null);
            for (Project project : projectList) {
                ProjectInfo projectInfo = new ProjectInfo();
                List<ProjectMember> projectMemberList = projectMemberMapper.selectList(new QueryWrapper<ProjectMember>().eq("pro_id", project.getProId()));
                List<ProjectSearching> projectSearchingList = projectSearchingMapper.selectList(new QueryWrapper<ProjectSearching>().eq("pro_id", project.getProId()));
                List<ProjectTeaching> projectTeachingList = projectTeachingMapper.selectList(new QueryWrapper<ProjectTeaching>().eq("pro_id", project.getProId()));
                projectInfo.setProject(project);
                projectInfo.setMembers(projectMemberList);
                projectInfo.setSearchings(projectSearchingList);
                projectInfo.setTeachings(projectTeachingList);
                projectInfos.add(projectInfo);
                redisUtils.set("project", projectInfos, expireTime);
            }
        }
        return Result.success(ResultCode.SUCCESS, projectInfos);
    }

    @Override
    public Result getProjectById(String proId) throws SQLException {
        Project project = projectMapper.selectOne(new QueryWrapper<Project>().eq("pro_id", proId));
        ProjectInfo projectInfo = new ProjectInfo();
        List<ProjectMember> projectMemberList = projectMemberMapper.selectList(new QueryWrapper<ProjectMember>().eq("pro_id", project.getProId()));
        List<ProjectSearching> projectSearchingList = projectSearchingMapper.selectList(new QueryWrapper<ProjectSearching>().eq("pro_id", project.getProId()));
        List<ProjectTeaching> projectTeachingList = projectTeachingMapper.selectList(new QueryWrapper<ProjectTeaching>().eq("pro_id", project.getProId()));

        projectInfo.setProject(project);
        projectInfo.setMembers(projectMemberList);
        projectInfo.setSearchings(projectSearchingList);
        projectInfo.setTeachings(projectTeachingList);

        return Result.success(ResultCode.SUCCESS, projectInfo);
    }

    @Override
    public Result getProjectByBatchId(String batchId) throws SQLException {
        return Result.success(ResultCode.SUCCESS, viewProjectMemberService.list(new QueryWrapper<ViewProjectMember>().eq("batch_id", batchId)));
    }

    @Override
    public Result getRecentProject(String batch_id, HttpServletRequest request) throws SQLException {
        String token = request.getHeader("token");
        if (token == null) {
            return Result.failure(ResultCode.USER_AUTH_Login_LAPSE);
        }
        String gh = jwtTokenUtil.getGHFromToken(token);
        //找到该批次下最近一次项目信息
        //获取该项目编号
        String pro_id = viewProjectMapper.getRecentProject(batch_id, gh);
        ProjectInfo projectInfo = new ProjectInfo();
        //查询工作简历信息
        List<ProjectSearching> projectSearchingList = viewProjectMapper.selectSearchingList(pro_id);
        //查询教学经历信息
        List<ProjectTeaching> projectTeachingList = viewProjectMapper.selectTeachingList(pro_id);

        projectInfo.setSearchings(projectSearchingList);
        projectInfo.setTeachings(projectTeachingList);

        return Result.success(ResultCode.SUCCESS, projectInfo);
    }

    @Override
    public void updateRides() {
        redisUtils.del("project");
        redisUtils.del("projectByBatchId");
    }

    @Override
    public Result creatProjects(Project project, String projectMembers, String projectSearchings, String projectTeachings) throws SQLException {
        String pro_id = UUIDUtils.getUUID();

        project.setProId(pro_id);

        List<ProjectMember> projectMemberList;
        List<ProjectSearching> projectSearchingList;
        List<ProjectTeaching> projectTeachingList;
        try {
            projectMemberList = JSON.parseArray(projectMembers, ProjectMember.class);
            projectSearchingList = JSON.parseArray(projectSearchings, ProjectSearching.class);
            projectTeachingList = JSON.parseArray(projectTeachings, ProjectTeaching.class);
        } catch (JSONException e) {
            return Result.failure(ResultCode.PARAM_JSON_IS_WRONG, e.getMessage());
        }

        for (ProjectMember projectMember : projectMemberList) {
            projectMember.setProId(pro_id);
        }
        for (ProjectSearching projectSearching : projectSearchingList) {
            projectSearching.setProId(pro_id);
        }
        for (ProjectTeaching projectTeaching : projectTeachingList) {
            projectTeaching.setProId(pro_id);
        }

        int resProject = projectService.creatProject(project);
        int resProjectMember = projectMemberService.creatProjectMemberList(projectMemberList);
        int resProjectSearching = projectSearchingService.creatProjectSearchingList(projectSearchingList);
        int resProjectTeaching = projectTeachingService.creatProjectTeachingList(projectTeachingList);


        if (resProject > 0 && resProjectMember > 0 && resProjectSearching > 0 && resProjectTeaching > 0) {
            return Result.success(ResultCode.SUCCESS);
        }
        return Result.failure(ResultCode.FAILURE);
    }

    @Override
    public Result deleteProject(String proId) throws SQLException {
        int resProject = projectService.deleteProject(proId);
        int resProjectMember = projectMemberService.deleteProjectMemberByProId(proId);
        int resProjectSearching = projectSearchingService.deleteProjectSearchingByProId(proId);
        int resProjectTeaching = projectTeachingService.deleteProjectTeachingByProId(proId);

        if (resProject > 0 || resProjectMember > 0 || resProjectSearching > 0 || resProjectTeaching > 0) {
            return Result.success(ResultCode.SUCCESS);
        }
        return Result.failure(ResultCode.FAILURE);
    }

    @Override
    public Result updateProject(Project project, String projectMembers, String projectSearchings, String projectTeachings) throws SQLException {

        List<ProjectMember> projectMemberList;
        List<ProjectSearching> projectSearchingList;
        List<ProjectTeaching> projectTeachingList;
        try {
            projectMemberList = JSON.parseArray(projectMembers, ProjectMember.class);
            projectSearchingList = JSON.parseArray(projectSearchings, ProjectSearching.class);
            projectTeachingList = JSON.parseArray(projectTeachings, ProjectTeaching.class);
        } catch (Exception e) {
            return Result.failure(ResultCode.PARAM_JSON_IS_WRONG, e.getMessage());
        }

        for (ProjectMember projectMember : projectMemberList) {
            projectMember.setProId(project.getProId());
        }
        for (ProjectSearching projectSearching : projectSearchingList) {
            projectSearching.setProId(project.getProId());
        }
        for (ProjectTeaching projectTeaching : projectTeachingList) {
            projectTeaching.setProId(project.getProId());
        }

        int resProject = projectService.updateProject(project);
        int resProjectMember = projectMemberService.updateProjectMemberList(projectMemberList);
        int resProjectSearching = projectSearchingService.updateProjectSearchingList(projectSearchingList);
        int resProjectTeaching = projectTeachingService.updateProjectTeachingList(projectTeachingList);

        if (resProject > 0 && resProjectMember > 0 && resProjectSearching > 0 && resProjectTeaching > 0) {
            return Result.success(ResultCode.SUCCESS);
        }
        return Result.failure(ResultCode.FAILURE);
    }


    @Override
    public Result selectMaxHost(String batch_id) {
        QueryWrapper<ViewProject> qw = new QueryWrapper<>();
        qw.select("count(pro_id)").eq("batch_id", batch_id).eq("ranking", 1).groupBy("belong");//查询自定义列
        List<Object> integer = viewProjectMapper.selectObjs(qw);
        if (!VerifycUtils.verifyNullOrEmptyUtils(integer)) {
            return Result.failure(ResultCode.SUCCESS, -1);
        }
        String s = JSON.toJSONString(integer);
        List<Integer> integerList = JSON.parseArray(s, Integer.class);
        try {
            return Result.success(ResultCode.SUCCESS, Collections.max(integerList));
        } catch (Exception e) {
            return Result.failure(ResultCode.No_Such_Element_Exception, -1);
        }
    }

    @Override
    public Result selectMaxParticipants(String batch_id) {
        QueryWrapper<ViewProject> qw = new QueryWrapper<>();
        qw.select("pro_id").eq("batch_id", batch_id).ne("ranking", 1).groupBy("belong");
        List<Object> integer = viewProjectMapper.selectObjs(qw);
        if (!VerifycUtils.verifyNullOrEmptyUtils(integer)) {
            return Result.failure(ResultCode.SUCCESS, -1);
        }
        String s = JSON.toJSONString(integer);
        List<Integer> integerList = JSON.parseArray(s, Integer.class);
        try {
            return Result.success(ResultCode.SUCCESS, Collections.max(integerList));
        } catch (Exception e) {
            return Result.failure(ResultCode.No_Such_Element_Exception, -1);
        }
    }

    @Override
    public Result selectClassificationByBatchId(String batch_id) {
        QueryWrapper<ViewProject> qw = new QueryWrapper<>();
        qw.select("classification");//查询自定义列
        qw.eq("batch_id", batch_id);
        qw.groupBy("classification");
        List<ViewProject> viewProjectList = viewProjectMapper.selectList(qw);
        List<String> resList = new ArrayList<>();
        for (ViewProject viewProject : viewProjectList) {
            resList.add(viewProject.getClassification());
        }
        if (VerifycUtils.verifyNullOrEmptyUtils(resList))
            return Result.success(ResultCode.SUCCESS, resList);
        return Result.failure(ResultCode.FAILURE);
    }

    @Override
    public Result getProjectsByGH(String gh) {
        QueryWrapper<ViewProject> viewProjectQueryWrapper = new QueryWrapper<>();
        viewProjectQueryWrapper.eq("belong", gh).eq("ranking", 1);
        List<ViewProject> viewProjectList = viewProjectMapper.selectList(viewProjectQueryWrapper);
        if (VerifycUtils.verifyNullOrEmptyUtils(viewProjectList))
            return Result.success(ResultCode.SUCCESS, viewProjectList);
        return Result.failure(ResultCode.FAILURE);
    }

    @Override
    public List<String> getProIdByBatchId(String batchId) {
        return viewProjectMapper.getProIdByBatchId(batchId);
    }

    @Override
    public List<MyProjectInfo> getSimplifyProjectsByGH(String gh, Integer ranking) {
        if (ranking == 1)
            return viewProjectMapper.getHostProjectsByGH(gh);
        return viewProjectMapper.getPartakeProjectsByGH(gh);
    }

    @Override
    public Result getSimplifyProjectByBatchId(String batch_id,String pro_approvals) {
        List<Integer> pro_approvalList = JSONToArrUtils.jsonToArr(pro_approvals, Integer.class );
        if (pro_approvalList == null) {
            return Result.failure(ResultCode.PARAM_JSON_IS_WRONG);
        }
        List<SimplifyProjectInfo> res = new ArrayList<>();
        for (Integer pro_approval : pro_approvalList) {
            List<SimplifyProjectInfo> resList = viewProjectMapper.getSimplifyProjectByBatchId(batch_id, pro_approval);
            res.addAll(resList);
        }
        return Result.success(ResultCode.SUCCESS, res);
    }

    @Override
    public Result getAllDelayProject() {
        List<DelayProject> delayProjects = viewProjectMapper.getAllDelayProject(24);
        return Result.success(ResultCode.SUCCESS, delayProjects);
    }

    @Override
    public Result getAllDelayProjectById(String proApprovals) {
        List<Integer> proApprovalList = JSONToArrUtils.jsonToArr(proApprovals, Integer.class);
        if (proApprovalList == null) {
            return Result.failure(ResultCode.PARAM_JSON_IS_WRONG);
        }
        List<DelayProject> res = new ArrayList<>();
        for (Integer proApproval : proApprovalList) {
            List<DelayProject> resList = viewProjectMapper.getAllDelayProject(proApproval);
            res.addAll(resList);
        }
        return Result.success(ResultCode.SUCCESS, res);
    }

    @Override
    public List<Dealt> getTeacherDealt(String gh) {
        return viewProjectMapper.getTeacherDealt(gh);
    }

    @Override
    public Result getSimplifyProjectByPhaseId(String phaseId) {
        List<SimplifyProjectInfo> resList = viewProjectMemberService.getSimplifyProjectByPhaseId(phaseId);
        return Result.success(ResultCode.SUCCESS, resList);
    }
}
